#include <stdio.h>
#include <stdlib.h>

typedef struct ListNode {
    int val;
    struct ListNode *next;
} ListNode;

// 创建新节点
ListNode* newNode(int val) {
    ListNode *node = (ListNode*)malloc(sizeof(ListNode));
    node->val = val;
    node->next = NULL;
    return node;
}

// 向有序链表插入新元素
void insert(ListNode** head, int val) {
    ListNode *temp = newNode(val);
    if (*head == NULL || (*head)->val >= val) {
        temp->next = *head;
        *head = temp;
    } else {
        ListNode *current = *head;
        while (current->next != NULL && current->next->val < val)
            current = current->next;
        temp->next = current->next;
        current->next = temp;
    }
}

// 集合并集
ListNode* unionSet(ListNode* l1, ListNode* l2) {
    if (l1 == NULL&&l2 == NULL)return NULL;
    
    ListNode *head=NULL;
    while (l1!=NULL&&l2!=NULL){
        
        if (l1->val<l2->val){
            insert(&head,l1->val);
            l1=l1->next;
        }
        else if (l1->val>l2->val){
            insert(&head,l2->val);
            l2=l2->next;
        }
        else{
            insert(&head,l1->val);
            l1=l1->next;
            l2=l2->next;
        }
    }
    if (l1==NULL){
        while (l2!=NULL){
            insert(&head,l2->val);
            l2=l2->next;
        }
    }
    else{
        while (l1!=NULL){
            insert(&head,l1->val);
            l1=l1->next;
        }
    }
    return head;
}

// 集合差集
ListNode* differenceSet(ListNode* l1, ListNode* l2) {
    if (l1==NULL) return NULL;
    ListNode *head=NULL;
    if (l2==NULL){
        while (l1!=NULL){
            insert(&head,l1->val);
            l1=l1->next;
        }
        return head;
    }
    
    while (l1!=NULL&&l2!=NULL){
        if (l1->val<l2->val){
            insert(&head,l1->val);
            l1=l1->next;
        }
        else if (l1->val>l2->val){
            l2=l2->next;
        }
        else {
            l1=l1->next;
            l2=l2->next;
        }
    }
    return head;
}

// 集合交集
ListNode* intersectionSet(ListNode* l1, ListNode* l2) {
    if (l1==NULL||l2==NULL)return NULL;
    ListNode *head=NULL;
    while (l1!=NULL&&l2!=NULL){
        if (l1->val<l2->val){
            l1=l1->next;
        }
        else if (l1->val>l2->val){
            l2=l2->next;
        }
        else {
            insert(&head,l1->val);
            l1=l1->next;
            l2=l2->next;
        }
    }
    return head;
}

// 打印链表，考虑空链表的情况
void printList(ListNode* head) {
    if (!head) {
        printf("\n"); // 空链表直接输出换行
        return;
    }

    while (head) {
        printf("%d", head->val);
        head = head->next;
        if (head) printf(" "); // 只有在后面还有元素时才打印空格
    }
    printf("\n");
}



// 释放链表内存
void freeList(ListNode* head) {
    
    ListNode* temp;
    while (head) {
        temp = head;
        head = head->next;
        free(temp);
    }
}

int main() {
    int n, m, val;
    ListNode *l1 = NULL, *l2 = NULL;

    // 读取第一个集合
    scanf("%d", &n);
    for (int i = 0; i < n; ++i) {
        scanf("%d", &val);
        insert(&l1, val);
    }

    // 读取第二个集合
    scanf("%d", &m);
    for (int i = 0; i < m; ++i) {
        scanf("%d", &val);
        insert(&l2, val);
    }

    // 计算并打印并集
    ListNode* unionResult = unionSet(l1, l2);
    printList(unionResult);

    // 计算并打印差集
    ListNode* diffResult = differenceSet(l1, l2);
    printList(diffResult);

    // 计算并打印交集
    ListNode* interResult = intersectionSet(l1, l2);
    printList(interResult);

    // 释放链表内存
    freeList(l1);
    freeList(l2);
    freeList(unionResult);
    freeList(diffResult);
    freeList(interResult);

    return 0;
}